package com.doitedu.day03.funcs
import scala.collection.immutable

/**
 * @Date 22.6.22
 * @Created by HANGGE
 * @Description
 * map方法不支持偏函数
 * collect方法支持偏函数
 */
object _05Collect方法 {
  def main(args: Array[String]): Unit = {
    // Any
    val ls: Seq[Any] = List(1,2,3,4,5,"java", "js" , "sql" , true , 'a')
    // 处理集合中的数字  数字平方
  /*   方式一  守卫模式 推导式
     val res = for (elem <- ls if elem.isInstanceOf[Int]) yield {
      val number = elem.asInstanceOf[Int]
     number*number
    }*/
    // 方式二  filter 过滤  再map
   val list = ls.filter(_.isInstanceOf[Int]).map(e => Math.pow(e.asInstanceOf[Int], 2).toInt)

   // 方式3 ************************偏函数********************
    // 专门用来处理某种数据类型的函数  偏函数 {接收Any , 判断是否是要处理的数据类型  处理}
    // 偏函数本质是一个特质(接口)

    // 定义一个偏函数实例
    /**
     * trait PartialFunction 特质(接口)
     * 泛型1 : 接收的数据类型
     * 泛型2 : 需要处理的数据类型
     *
     */
    val  pf: PartialFunction[Any, String] = new PartialFunction[Any  ,String] {
      /**
       * isDefinedAt 判断集合中的每个方法是否是某种数据类型  是 返回true
       * 执行下面的方法
       * apply  处理数据的方法
       * @param x
       * @return
       */
      // 实现抽象方法
      override def isDefinedAt(x: Any): Boolean = {
        x.isInstanceOf[String]
      }
      // 实现抽象方法  处理上个方法返回true的元素
      override def apply(v1: Any): String = {
        v1.asInstanceOf[String].toUpperCase
      }
    }
    /**
     * 1 isDefinedAt
     * 2 apply
     * collet和map一样 处理集合中的每个元素
     * 数据:  1 2 3 4 5  java  sql  js
     *     执行过程
     * 1.遍历集合中的各个元素
     * 2.各个元素首先会经过 isDefinedAt  判断是否是String类型 结果 true  false
     * 3.如果返回true 再接着调用 apply方法处理当前元素
     * 4.将处理后的结果收集到集合中
     */
   // val res = ls.collect(pf)
   // res.foreach(println)
    println("----------------------")
      // 定义一个返回值是偏函数的方法
    def  myPf:PartialFunction[Any,Int]={
      new  PartialFunction[Any,Int] {
        override def isDefinedAt(x: Any): Boolean = {
          x.isInstanceOf[Int]
        }
        override def apply(v1: Any): Int = {
          v1.asInstanceOf[Int] *10
        }
      }
    }

    val res = ls.collect(myPf)
    res.foreach(println)

    println("-----------简写方式1-----------")

    def myPf2:PartialFunction[Any,Int]={
          // 底层是偏函数 判断每个元素是否是 Int类型
      case x:Int=>x*x
    }
    ls.collect(myPf2).foreach(println)

    println("-----------简写方式2-----------")
   // ls.collect({
    // case x:String=>x.toUpperCase()
    // }).foreach(println)
    // 底层是偏函数
    // 接收的的类型一般是Any   待处理的类型也是Any(处理要处理的多个数据类型)
    val res2: Seq[Any] = ls.collect {
      case x: String => x.toUpperCase
      case x: Int => x * x
    }

  }

}
